package com.xexun.gpstracker;

import java.io.*;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Locale;

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.util.Log;

import org.simple.eventbus.EventBus;
import org.xutils.DbManager;
import org.xutils.x;

import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiskCache;
import com.nostra13.universalimageloader.cache.disc.naming.HashCodeFileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.decode.BaseImageDecoder;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import com.xexun.gpstracker.common.Constants;
import com.xexun.gpstracker.common.CrashHandler;
import com.xexun.gpstracker.listener.XXDbUpgradeListener;
import com.xexun.gpstracker.util.CommUtil;
import com.xexun.gpstracker.util.DigestUtils;
import com.xexun.gpstracker.util.FileUtils;
import com.xexun.gpstracker.util.Utils;
import com.xexun.gpstracker.vo.FlavorType;

/**
 * Created by HH
 * Date: 2015/6/24 0024
 * Time: 下午 8:26
 */
public class AppContext extends Application {
    private static AppContext context;
    public static Context applicationContext;
    public static DbManager db = null;
    public static boolean isEntered = false;
    public static int termType = 0;//0或空为手表，1 为手铐
    private static EventBus eventBus;
    public static boolean forceLogout = false;
    public static LinkedList<Long> newChatMsgIds = new LinkedList<>();
    public static boolean managerInfoChecked = false;

    @Override
    public void onConfigurationChanged(Configuration config) {
        super.onConfigurationChanged(config);
        config.locale = Locale.getDefault();
        Resources resources = getResources();
        resources.updateConfiguration(config, resources.getDisplayMetrics());
        Constants.LOCALE = config.locale.toString();
        Constants.IS_CHINA_VERSION = Locale.CHINESE.getLanguage().equalsIgnoreCase(config.locale.getLanguage());
        loadIPConfig();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        context = this;
        applicationContext = getApplicationContext();

        Resources resources = getResources();
        Configuration config = resources.getConfiguration();
        config.locale = Locale.getDefault();
        resources.updateConfiguration(config, resources.getDisplayMetrics());
        Constants.IS_CHINA_VERSION = Locale.CHINESE.getLanguage().equalsIgnoreCase(config.locale.getLanguage());//getMetaData(this, "IS_CHINA_VERSION") == 1;

        //全局异常捕获
        CrashHandler crashHandler = CrashHandler.getInstance();
        crashHandler.init(getApplicationContext());

        eventBus = EventBus.getDefault();

        x.Ext.init(this);
        x.Ext.setDebug(true);

        String dbName = getMetaData(this, "DB_NAME");
        int dbVersion = CommUtil.toInteger(getMetaData(this, "DB_VERSION"), 0);
        File dbFile = copyAttachedDatabase(this, dbName);

        DbManager.DaoConfig daoConfig = new DbManager.DaoConfig()
                .setDbName(dbName)
                .setDbDir(dbFile.getParentFile())
                .setDbVersion(dbVersion)
                .setDbUpgradeListener(new XXDbUpgradeListener());
        db = x.getDb(daoConfig);

        loadIPConfig();


        ImageLoader.getInstance().init(getImageLoaderConfiguration());

        InputStream in = null;
        try {
            in = getAssets().open("qm.sec");
            DigestUtils.appKeysList = Arrays.asList(new String(FileUtils.readInputStream(in)).split(","));
        } catch (Exception e) {
            Log.e(AppContext.class.getName(), "Load keys failed", e);
        } finally {
            FileUtils.closeInputStream(in);
        }
        Constants.secKey = getMetaData(this, "qm_sec");
        Constants.secUse = (int)getMetaData(this, "qm_sec_use") == 1;

        try {
            PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), 0);
            Constants.versionCode = info.versionCode;
            Constants.versionName = info.versionName;

        } catch (PackageManager.NameNotFoundException e) {
            //
        }
        Constants.FLAVOR = FlavorType.getFlavorType(CommUtil.toStr(getMetaData(this, "FLAVOR")));
    }

    private void loadIPConfig() {
        Constants.baseUrl = Utils.getBaseUrlFromMeta(this);
        String updateUrl = CommUtil.toStr(getMetaData(this, "UPDATE_URL"));
        if (updateUrl.startsWith("http://")) {
            Constants.UPDATE_URL = updateUrl;
        } else {
            Constants.UPDATE_URL = Constants.baseUrl + "/" + updateUrl;
        }

        SharedPreferences preferences = Utils.getPreferences(AppContext.getContext());
        String ip = preferences.getString(Constants.SETTING_SERVER_IP, null);
        if (CommUtil.isBlank(ip) || !ip.matches(Constants.REGX_IP_PORT)) {
            String domain = Utils.getMetaValue(AppContext.getContext(), Constants.IS_CHINA_VERSION ? "domain" : "domain_en");
            String serIP = Utils.getMetaValue(AppContext.getContext(), "chat_server_IP");
            ip = serIP.replaceAll("\\{domain\\}", domain);
        }
        Constants.baseServerIP = ip;
    }

    public static Context getContext() {
        return context;
    }

    public static EventBus getEventBus() {
        return eventBus;
    }


    public static <T> T getMetaData(Context context, String name) {
        try {
            final ApplicationInfo ai = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
            if (ai.metaData != null) {
                return (T) ai.metaData.get(name);
            }
        } catch (Exception e) {
            Log.w(Constants.TAG, "Couldn't find meta-data: " + name);
        }

        return null;
    }

    public File copyAttachedDatabase(Context context, String dbName) {
        final File dbFile = context.getDatabasePath(dbName);

        // If the database already exists, return
        if (dbFile.exists()) {
//            dbPath.delete();
            return dbFile;
        }

        // Make sure we have a path to the file
        dbFile.getParentFile().mkdirs();

        // Try to copy database file
        try {
            final InputStream inputStream = context.getAssets().open(dbName);
            final OutputStream output = new FileOutputStream(dbFile);

            byte[] buffer = new byte[1024];
            int length;

            while ((length = inputStream.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }

            output.flush();
            output.close();
            inputStream.close();
        } catch (IOException e) {
            Log.e(Constants.TAG, "Failed to open file", e);
        }
        return dbFile;
    }

    public ImageLoaderConfiguration getImageLoaderConfiguration() {
        return new ImageLoaderConfiguration.Builder(context)
                .memoryCacheExtraOptions(300, 300) // default = device screen dimensions
//                .diskCacheExtraOptions(500, 500, null)
                .threadPoolSize(5) // default
                .threadPriority(Thread.NORM_PRIORITY - 1) // default
                .tasksProcessingOrder(QueueProcessingType.FIFO) // default
                .denyCacheImageMultipleSizesInMemory()
                .memoryCache(new LruMemoryCache(2 * 1024 * 1024))
                .memoryCacheSize(2 * 1024 * 1024)
                .memoryCacheSizePercentage(13) // default
                .diskCache(new UnlimitedDiskCache(new File(Utils.getAvailableStoragePath() + "pic"))) // default
                .diskCacheSize(100 * 1024 * 1024)
                .diskCacheFileCount(100)
                .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
                .imageDownloader(new BaseImageDownloader(context)) // default
                .imageDecoder(new BaseImageDecoder(true)) // default
                .defaultDisplayImageOptions(new DisplayImageOptions.Builder().cacheInMemory(true).cacheOnDisk(true).build())
//                .writeDebugLogs()
                .build();
    }


}
